//
//  ViewController.m
//  Ble4.0-SrialPort
//
//  Created by Mike on 15/7/7.
//  Copyright (c) 2015年 MaxWiLL. All rights reserved.
//

#define kUUID @"ffe0"
#import "ViewController.h"
#import <CoreBluetooth/CoreBluetooth.h>
#import <CoreBluetooth/CBService.h>
#import "BLESettingTableViewController.h"



@interface ViewController () <CBCentralManagerDelegate, CBPeripheralDelegate, BLESettingTableViewControllerDelegate>


/** 输入框 */
@property (strong, nonatomic) IBOutlet UITextField *inputTextField;
/** 蓝牙管理器 */
@property (nonatomic, strong) CBCentralManager *manager;



/** 接收的展示数据的TextView */
@property (weak, nonatomic) IBOutlet UITextView *receiveTextView;
/** 特征 */
@property (strong, nonatomic) CBCharacteristic *characteristic;
/** 接收到得字符串 */
@property (copy, nonatomic) NSMutableString *receiveTotalStr;

/** 蓝牙连接状态 */
@property (weak, nonatomic) IBOutlet UILabel *connectStateLable;

/** 显示接收到的 */
@property (weak, nonatomic) IBOutlet UILabel *receiveLable;

@property (weak, nonatomic) IBOutlet UILabel *sendLable;
@property (nonatomic, assign) NSUInteger sendCount;

/** 外设 */
@property (nonatomic, strong) CBPeripheral *peripheral;


@property (nonatomic, assign) BOOL isHEX;

@end

@implementation ViewController

- (NSMutableString *)receiveTotalStr {
    if ( _receiveTotalStr == nil) {
        _receiveTotalStr = [NSMutableString string];
    }
    return _receiveTotalStr;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 初始化蓝牙管理器
    _manager = [[CBCentralManager alloc] initWithDelegate:self queue:nil];
    
    // 监听键盘
    [self setupKeyboardNotification];
    
    // 连接蓝牙通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(bluetoothDidFind:) name:@"selectedBluetoothNotification" object:nil];
    
}


/**
 *  连接蓝牙
 *
 *  @param notification 通知
 */
-(void) bluetoothDidFind:(NSNotification *)notification {
    
    NSDictionary *dict = notification.userInfo;
    
    self.peripheral = dict[@"peripheral"];
    
    // 重新扫描
    [self.manager scanForPeripheralsWithServices:nil options:nil];
  
}

/**
 *  数据格式转换按钮事件
 */
- (IBAction)switchFormat:(UIButton *)btn {
    btn.selected = !btn.isSelected;
    if (btn.selected) {  // HEX 格式
        self.inputTextField.text = [self hexStringFromString:self.inputTextField.text];
        self.isHEX = YES;
    }else {
        self.isHEX = NO;
        self.inputTextField.text = [self stringFromHexString:self.inputTextField.text];
    }
}

/**
 *  字符串转16进制
 */
- (NSString *)hexStringFromString:(NSString *)string {
    NSData *myD = [string dataUsingEncoding:NSUTF8StringEncoding];
    Byte *bytes = (Byte *)[myD bytes];
    // 把Byte转换为16 进制
    NSString *hexStr=@"";
    for (int i = 0; i < myD.length; i ++) {
        NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i]&0xff]; // 16进制
        if (newHexStr.length == 1) {
            hexStr = [NSString stringWithFormat:@"%@0%@", hexStr, newHexStr];
        } else {
            hexStr = [NSString stringWithFormat:@"%@%@", hexStr, newHexStr];
        }
    }
    return hexStr;
}

/**
 *  16进制转字符串
 */
- (NSString *)stringFromHexString:(NSString *)hexString {
    char *myBuffer = (char *)malloc((int)hexString.length/2 + 1);
    bzero(myBuffer, hexString.length / 2 +1);
    for (int i = 0; i < hexString.length - 1; i += 2) {
        unsigned int anInt;
        NSString *hexCharStr = [hexString substringWithRange:NSMakeRange(i, 2)];
        NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
        [scanner scanHexInt:&anInt];
        myBuffer[i / 2] = (char)anInt;
    }
    NSString *unicodeString = [NSString stringWithCString:myBuffer encoding:4];
    return unicodeString;
}

/**
 *  发送数据
 *
 *  @param sender 发送按钮
 */
- (IBAction)send:(UIButton *)sender {
    
    NSString *text = self.inputTextField.text;
    
    NSData *data = [text dataUsingEncoding:NSUTF8StringEncoding];

    // 写数据
    [self.peripheral writeValue:data forCharacteristic:self.characteristic type:CBCharacteristicWriteWithoutResponse];
    
    self.sendCount += text.length;
    self.sendLable.text = [NSString stringWithFormat:@"已经发送：%lu", (unsigned long)self.sendCount];
    
    NSLog(@"%@", text);
}




#pragma mark - CBCentralManagerDelegate
/**
 *  主设备状态改变，只有在设备正确打开后才能使用
 */
- (void)centralManagerDidUpdateState:(CBCentralManager *)central{
    NSLog(@"蓝牙状态改变");
    /*
     CBCentralManagerStateUnknown = 0,
     CBCentralManagerStateResetting,
     CBCentralManagerStateUnsupported,
     CBCentralManagerStateUnauthorized,
     CBCentralManagerStatePoweredOff,
     CBCentralManagerStatePoweredOn,
     */
    switch (central.state) {
        case CBCentralManagerStateUnknown:
            NSLog(@"CBCentralManagerStateUnknown");
            break;
        case CBCentralManagerStateResetting:
            NSLog(@"CBCentralManagerStateResetting");
            break;
        case CBCentralManagerStateUnsupported:
            NSLog(@"CBCentralManagerStateUnsupported");
            break;
        case CBCentralManagerStateUnauthorized:
            NSLog(@"CBCentralManagerStateUnauthorized");
            break;
        case CBCentralManagerStatePoweredOff:
            NSLog(@"CBCentralManagerStatePoweredOff");
            break;
        case CBCentralManagerStatePoweredOn:
            NSLog(@"CBCentralManagerStatePoweredOn");
            break;
        default:
            break;
    }

}

/**
 *  扫描到外设时调用
 */
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI{
   
    NSLog(@"重新扫描到外设");
    // 如果所选的设备和当前扫描的设备一样
    if ([self.peripheral.name isEqualToString:peripheral.name]) {
        NSLog(@"所选设备和扫描设备一样");
        self.peripheral = peripheral;
        [self.manager connectPeripheral:peripheral options:nil];
    }
   

    
}

/**
 *  连接外设成功
 */
- (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral{
    
    peripheral.delegate = self;
    
    self.connectStateLable.backgroundColor = [UIColor greenColor];
    self.connectStateLable.text = @"已连接";
    
    NSLog(@"已经连接");

    // 扫描全部服务
    [peripheral discoverServices:nil];

}

/**
 *  连接外设失败
 */
- (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error{
    NSLog(@" %d | %s | %@",__LINE__,__FUNCTION__,error );
    
}

/**
 *  断开外设
 */
- (void)centralManager:(CBCentralManager *)central didDisconnectPeripheral:(CBPeripheral *)peripheral error:(NSError *)error {
     NSLog(@" %d | %s | %@",__LINE__,__FUNCTION__,error );
    
    self.connectStateLable.backgroundColor = [UIColor redColor];
    self.connectStateLable.text = @"未连接";
    
}

#pragma mark - CBPeripheralDelegate

/**
 *  扫描到服务
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)error{
    
    if (error) {
        NSLog(@" %d | %s | %@",__LINE__,__FUNCTION__,error );
        return;
    }
    
    NSLog(@"扫描到服务");
    // 获取外设中所有服务
    for (CBService *service in peripheral.services) {
        // 扫描每个服务的特征
        NSLog(@"service:  %@", service);
        [peripheral discoverCharacteristics:nil forService:service];
    }
}

/**
 *  扫描到特征
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForService:(CBService *)service error:(NSError *)error{
    if (error) {
        NSLog(@" %d | %s | %@",__LINE__,__FUNCTION__,error );
        return ;
    }
    
    // 遍历特征，拿到需要的特征
    for (CBCharacteristic *characteristic in service.characteristics) {
        
        //获取Characteristic的值，读到数据会进入方法：-(void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
        [peripheral readValueForCharacteristic:characteristic];
        
        //搜索Characteristic的Descriptors，读到数据会进入方法：-(void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error
        [peripheral discoverDescriptorsForCharacteristic:characteristic];
        
        NSLog(@"获得特征");
        self.characteristic = characteristic;
        [peripheral setNotifyValue:YES forCharacteristic:characteristic];
    }
}

/**
 *  获取到特征的值
 */
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    if (error) {
        NSLog(@" %d | %s | %@",__LINE__,__FUNCTION__,error);
        return;
    }
    NSLog(@"获取到特征值");
    // 接收数据
    NSString *reseiveStr = [[NSString alloc] initWithData:characteristic.value encoding:NSUTF8StringEncoding];
    
    [self.receiveTotalStr appendString:reseiveStr];
    self.receiveTextView.text = self.receiveTotalStr;
    self.receiveLable.text = [NSString stringWithFormat:@"已接收：%lu", self.receiveTotalStr.length-1];
    NSLog(@"%@",reseiveStr);
}

/**
 *  搜索到特征值的描述
 */
- (void)peripheral:(CBPeripheral *)peripheral didDiscoverDescriptorsForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error {
    NSLog(@"搜索到特征值的描述");
    for (CBDescriptor *d in characteristic.descriptors) {
        NSLog(@"Descriptor uuid:%@", d.UUID);
    }
    
}

/**
 *  获取到特征的描述
 */
- (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForDescriptor:(CBDescriptor *)descriptor error:(NSError *)error {
    NSLog(@"获取到特征的描述");
}

/**
 *
 */

- (void)peripheral:(CBPeripheral *)peripheral didUpdateNotificationStateForCharacteristic:(CBCharacteristic *)characteristic error:(NSError *)error{
    if (error) {
        NSLog(@" %d | %s | %@",__LINE__,__FUNCTION__,error);
        return;
    }
    
    if (characteristic.isNotifying) {
     //   NSLog(@" %d | %s | %@",__LINE__,__FUNCTION__,characteristic);
    }else{
      //  NSLog(@" %d | %s | %@ | %@",__LINE__,__FUNCTION__,characteristic,@"disconnected");
    }
    
}


#pragma mark - 键盘监听
/**
 *  监听键盘是否弹出，修改页面frame，是输入框不背遮住
 */
- (void)setupKeyboardNotification{
    
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillDismiss:) name:UIKeyboardWillHideNotification object:nil];
}

/**
 *  键盘即将显示
 */
- (void)keyboardWillShow:(NSNotification *)notification{
    NSDictionary *userInfo = [notification userInfo];
    NSValue *frameVale = userInfo[UIKeyboardFrameEndUserInfoKey];
    CGRect frame = self.view.frame;
    frame.size.height = [frameVale CGRectValue].origin.y;
    self.view.frame = frame;
}


/**
 *  键盘即将消失
 */
- (void)keyboardWillDismiss:(NSNotification *)notifcation{
    self.view.frame = [UIScreen mainScreen].bounds;
}


#pragma mark - UI事件处理
- (IBAction)history:(id)sender {
//    // 连接设备
//   [self.manager connectPeripheral:self.peripheral options:nil];
//   NSLog(@"手动连接设备");
}

- (IBAction)settingAction:(id)sender {
    
    NSLog(@"设置按钮");
    [_inputTextField resignFirstResponder];
    [_receiveTextView resignFirstResponder];
    BLESettingTableViewController *settingVc = [[BLESettingTableViewController alloc] init];
    
    settingVc.delegate = self;
    
    [self.navigationController pushViewController:settingVc animated:YES];
    
}

- (IBAction)swipeToRightAction:(id)sender {
    NSLog(@" %d | %s ",__LINE__,__FUNCTION__);
}

- (IBAction)swipeToLeftAction:(id)sender {
    NSLog(@" %d | %s ",__LINE__,__FUNCTION__);
}

- (IBAction)swipeUpAction:(id)sender {
    NSLog(@" %d | %s ",__LINE__,__FUNCTION__);
    [_inputTextField becomeFirstResponder];
}

// 下滑操作
- (IBAction)swipeDownAction:(id)sender {
    NSLog(@" %d | %s ",__LINE__,__FUNCTION__);
    [_inputTextField resignFirstResponder];
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

#pragma mark - BLESettingTableViewControllerDelegate 设置的代理方法

/**
 *  清除接收数据
 */
- (void)settingTableViewContrllerCleanBtnClick:(BLESettingTableViewController *)settingVC {
    
    // 清除接收框的数据
    self.receiveTextView.text = @"";
    
}
/**
 *  断开连接
 */
- (void)settingTableViewContrllerDisconnectBtnClick:(BLESettingTableViewController *)settingVC {
    //停止扫描
    [self.manager stopScan];
    //断开连接
    [self.manager cancelPeripheralConnection:self.peripheral];
}

@end
